//Documentation complete
/**
 * @author Alex
 * @version 2009FE28
 */

package problemDomain;

import static problemDomain.ErrorBean.*;
import static problemDomain.ErrorBean.ErrorCode.*;
import static utilities.XMLTools.encodeEntities;

import java.util.Calendar;

/**
 * Represents a table reservation.
 */
public class ReservationBean implements Bean {
	
	/* Constants */
	
	private static final long serialVersionUID = -1352481552348006918L;
	
	/* END Constants */
	
	
	/* Attributes */
	
	private int id;
	private String firstname;
	private String lastname;
	private String phone;
	private int numberPeople;
	private Calendar datePlaced;
	private Calendar date;
	private String description;
	private EmployeeAccountBean createdBy;
	private PatronAccountBean patron;

	/* END Attributes */
	
	
	/* Constructors */

	/**
	 * Constructs a reservation bean object with default values.
	 */
	public ReservationBean () {
		id = 0;
		datePlaced = null;
		date = null;
		numberPeople = 0;
		description = "";
		createdBy = null;
		firstname = "";
		lastname = "";
		phone = "";
	}

	/**
	 * Constructs a reservation bean object with specified reservation ID and
	 * other default values.
	 * @param reservationID The ID number of the reservation
	 */
	public ReservationBean (int reservationID) {
		this();
		this.id = reservationID;
	}

	/**
	 * Constructs a reservation bean object with all specified values.
	 * @param reservationID The ID number of the reservation
	 * @param firstname The first name of the patron who created the reservation
	 *        This is used when the patron is not registered
	 * @param lastname The last name of the patron who created the reservation
	 *        This is used when the patron is not registered
	 * @param phone The phone number of the patron who created the reservation
	 *        This is used when the patron is not registered
	 * @param numberPeople Number of people of the reservation.
	 * @param datePlaced The date when the reservation is placed
	 * @param reservationDate The date of the reservation
	 * @param description Description of the reservation, if anything.
	 * @param createdBy The employee account that created the reservation
	 * @param patron The patron account that placed the reservation

	 * 
	 */
	public ReservationBean (int reservationID, String firstname,
		String lastname, String phone, int numberPeople, Calendar datePlaced,
		Calendar reservationDate, String description,
		EmployeeAccountBean createdBy, PatronAccountBean patron) {
		this.createdBy = createdBy;
		this.patron = patron;
		this.datePlaced = datePlaced;
		this.description = description;
		this.numberPeople = numberPeople;
		this.firstname = firstname;
		this.lastname = lastname;
		this.phone = phone;
		this.date = reservationDate;
		this.id = reservationID;
	}

	/* END Constructors */
	
	
	/* Accessors */

	/**
	 * Returns the ID number of the reservation.
	 * @return the ID number of the reservation
	 */
	public int getReservationID () {
		return id;
	}

	/**
	 * Returns the date when the reservation is placed.
	 * @return the date when the reservation is placed
	 */
	public Calendar getDatePlaced () {
		return datePlaced;
	}

	/**
	 * Returns the date of the reservation.
	 * @return the date of the reservation
	 */
	public Calendar getReservationDate () {
		return date;
	}

	/**
	 * Returns the number of people of the reservation.
	 * @return the number of people of the reservation
	 */
	public int getNumberPeople () {
		return numberPeople;
	}

	/**
	 * Returns the description of the reservation.
	 * @return the description of the reservation
	 */
	public String getDescription () {
		return description;
	}

	/**
	 * Returns the employee account that created the reservation.
	 * @return the employee account that created the reservation
	 */
	public EmployeeAccountBean getCreatedBy () {
		return createdBy;
	}

	/**
	 * Returns the patron account that placed the reservation.
	 * @return the patron account that placed the reservation
	 */
	public PatronAccountBean getPatron () {
		return patron;
	}

	/**
	 * Returns the first name of the patron who created the reservation.
	 * Returns <code>null</code> if the reservation is made online by a registered patron.
	 * @return the first name of the patron who created the reservation
	 */
	public String getFirstname () {
		return firstname;
	}

	/**
	 * Returns the last name of the patron who created the reservation.
	 * Returns <code>null</code> if the reservation is made online by a registered patron.
	 * @return the last name of the patron who created the reservation
	 */
	public String getLastname () {
		return lastname;
	}

	/**
	 * Returns the phone number of the patron who created the reservation.
	 * Returns <code>null</code> if the reservation is made online by a registered patron.
	 * @return the phone number of the patron who created the reservation
	 */
	public String getPhone () {
		return phone;
	}

	/* END Accessors */
	
	
	/* Mutators */

	/**
	 * Sets the ID number of the reservation.
	 * @param reservationID the ID number of the reservation
	 */
	public void setReservationID (int reservationID) {
		this.id = reservationID;
	}

	/**
	 * Sets the date when the reservation is placed.
	 * @param datePlaced the date when the reservation is placed
	 */
	public void setDatePlaced (Calendar datePlaced) {
		this.datePlaced = datePlaced;
	}

	/**
	 * Sets the reservation date.
	 * @param reservationDate the reservation date
	 */
	public void setReservationDate (Calendar reservationDate) {
		this.date = reservationDate;
	}

	/**
	 * Sets the number of people.
	 * @param numberPeople the number of people
	 */
	public void setNumberPeople (int numberPeople) {
		this.numberPeople = numberPeople;
	}

	/**
	 * Sets the description.
	 * @param description the description
	 */
	public void setDescription (String description) {
		this.description = description;
	}

	/**
	 * Sets the employee which created the Reservation.
	 * @param createdBy the employee which created the Reservation.
	 */
	public void setCreatedBy (EmployeeAccountBean createdBy) {
		this.createdBy = createdBy;
	}

	/**
	 * Sets the patron.
	 * @param patron the patron
	 */
	public void setPatron (PatronAccountBean patron) {
		this.patron = patron;
	}

	/**
	 * Sets the first name.
	 * @param firstname the first name
	 */
	public void setFirstname (String firstname) {
		this.firstname = firstname;
	}

	/**
	 * Sets the last name.
	 * @param lastname the last name
	 */
	public void setLastname (String lastname) {
		this.lastname = lastname;
	}

	/**
	 * Sets the phone number.
	 * @param phone the phone number
	 */
	public void setPhone (String phone) {
		this.phone = phone;
	}

	/* END Mutators */
	
	
	/* (Bean) Methods */

	@Override
	public boolean isValid () throws ErrorBean {
		if (id < 0)
			throwError(
				RESERVATION_ID_INVALID,
				String.valueOf(id),
				this);

		if (firstname != null && firstname.length() > 30)
			throwError(
				RESERVATION_FIRSTNAME_INVALID,
				"First name is too long: " + firstname,
				this);

		if (lastname != null && lastname.length() > 30)
			throwError(
				RESERVATION_LASTNAME_INVALID,
				"Last name is too long: " + lastname,
				this);

		if (phone != null && !phone.matches("\\d{10}"))
			throwError(
				RESERVATION_PHONE_INVALID,
				phone,this);

		if (numberPeople > 100)
			throwError(
				RESERVATION_NUMBEROFPEOPLE_INVALID,
				"Number of people is more than 127: " + numberPeople,
				this);
		
		if (numberPeople <= 0)
			throwError(
					RESERVATION_NUMBEROFPEOPLE_INVALID,
					"Number of people is less than 1: " + numberPeople,
					this);

		if (datePlaced != null && datePlaced.after(Calendar.getInstance()))
			throwError(
				RESERVATION_DATEPLACED_INVALID,
				"Placed date is in the future: " + datePlaced,
				this);

		if (date != null && date.before(Calendar.getInstance()))
			throwError(
				RESERVATION_DATERESERVED_INVALID,
				"Reservation date is in the past: " + date,
				this);

		if (description != null && description.length() > 255)
			throwError(
				RESERVATION_DESCRIPTION_INVALID,
				"Description is too long: " + description,
				this);

		return true;
	}

	@Override
	public String toXML () {
		StringBuilder sb = new StringBuilder();
		sb.append("<reservation>");
		sb.append("<id>" + id + "</id>");
		sb.append("<firstname>" + firstname + "</firstname>");
		sb.append("<lastname>" + lastname + "</lastname>");
		sb.append("<phone>" + phone + "</phone>");
		sb.append("<placed>");
		sb.append("<day>" + (datePlaced != null ? datePlaced.get(Calendar.DAY_OF_MONTH) : "") + "</day>");
		sb.append("<month>" + (datePlaced != null ? datePlaced.get(Calendar.MONTH) : "") + "</month>");
		sb.append("<year>" + (datePlaced != null ? datePlaced.get(Calendar.YEAR) : "") + "</year>");
		sb.append("</placed>");
		sb.append("<date>");
		sb.append("<day>" + (date != null ? date.get(Calendar.DAY_OF_MONTH) : "") + "</day>");
		sb.append("<month>" + (date != null ? date.get(Calendar.MONTH) : "") + "</month>");
		sb.append("<year>" + (date != null ? date.get(Calendar.YEAR) : "") + "</year>");
		sb.append("<hour>" + (date != null ? date.get(Calendar.HOUR_OF_DAY) : "") + "</hour>");
		sb.append("<minute>" + (date != null ? date.get(Calendar.MINUTE) : "") + "</minute>");
		sb.append("</date>");
		sb.append("<number>" + numberPeople + "</number>");
		sb.append("<description>" + (description != null ? description : "") + "</description>");
		sb.append("<createdby>" + (createdBy != null ? createdBy.toXML() : "") + "</createdby>");
		sb.append(patron != null ? patron.toXML() : "<patron></patron>");
		sb.append("</reservation>");
		return encodeEntities(sb.toString());
	}

	/* END (Bean) Methods */
	
	
	/* (Object) Methods */

	@Override
	public String toString () {
		StringBuilder sb = new StringBuilder();
		sb.append("Reservation ID: " + id + '\n');
		sb.append("Date Placed: " + datePlaced + '\n');
		sb.append("Reservation Date: " + date + '\n');
		sb.append("Number Of People: " + numberPeople + '\n');
		sb.append("Description: " + description + '\n');
		sb.append("Created by: " + createdBy + '\n');
		sb.append("Patron: " + patron + '\n');
		sb.append("Patron First Name: " + firstname + '\n');
		sb.append("Patron Last Name: " + lastname + '\n');
		sb.append("Patron Phone No.:" + phone + "\n\n");
		return sb.toString();
	}

	/* END (Object) Method */
	
}
